package com.hrp.book.base

import android.os.Bundle
import android.view.View
import androidx.annotation.IdRes
import androidx.annotation.LayoutRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModelProvider
import com.xuexiang.xui.XUI
import me.yokeyword.fragmentation.ISupportFragment
import me.yokeyword.fragmentation.SupportActivity
import java.lang.reflect.GenericSignatureFormatError
import java.lang.reflect.MalformedParameterizedTypeException
import java.lang.reflect.ParameterizedType

abstract class BaseActivity<DB : ViewDataBinding, VM : BaseViewModel> : SupportActivity() {

    protected lateinit var binding: DB

    protected lateinit var viewModel: VM

    private var savedInstanceState: Bundle? = null

    private var initialized = false

    companion object {

        private var lastClickTime = 0L

        private const val CLICK_INTERVAL_TIME = 300L

        val isRepeatClick: Boolean
            get() {
                val currentTime = System.currentTimeMillis()
                if (currentTime - lastClickTime > CLICK_INTERVAL_TIME) {
                    lastClickTime = currentTime
                    return false
                }
                return true
            }


    }


    override fun onCreate(savedInstanceState: Bundle?) {
        XUI.initTheme(this);
        super.onCreate(savedInstanceState)
        this.savedInstanceState = savedInstanceState
        binding = DataBindingUtil.setContentView(this, getLayoutId())
        if (hasViewModel()) {
            viewModel = createViewModel()
        }
    }

    @Suppress("UNCHECKED_CAST")
    protected open fun getViewModelClass(): Class<VM> {
        var temp: Class<*>? = javaClass
        var z: Class<*>? = null
        while (z == null && null != temp) {
            z = getInstancedGenericKClass(temp)
            temp = temp.superclass
        }
        // 泛型擦除会导致z为null
        return (z ?: BaseViewModel::javaClass) as Class<VM>
    }

    protected open fun createViewModel(): VM {
        return ViewModelProvider(this).get(getViewModelClass())
    }


    @LayoutRes
    abstract fun getLayoutId(): Int

    abstract fun onLazyInitView(savedInstanceState: Bundle?)


    open fun hasViewModel(): Boolean {
        return true
    }

    override fun onResume() {
        super.onResume()
        if (!initialized) {
            initialized = true
            if (hasViewModel()) {
                viewModel.initialize()
            }
            onLazyInitView(savedInstanceState)
        }
    }

    open fun loadRootFragment(toFragment: ISupportFragment) {
        loadRootFragment(getContainerId(), toFragment)
    }

    fun loadMultipleRootFragment(
        showPosition: Int,
        vararg toFragments: ISupportFragment?
    ) {
        loadMultipleRootFragment(getContainerId(), showPosition, *toFragments)
    }


    @IdRes
    open fun getContainerId(): Int {
        return View.NO_ID
    }


    /**
     * get generic parameter VM
     *
     * @param z
     * @return
     */
    private fun getInstancedGenericKClass(z: Class<*>): Class<*>? {
        try {
            val type = z.genericSuperclass
            if (type is ParameterizedType) {
                val types = type.actualTypeArguments
                for (temp in types) {
                    if (temp is Class<*>) {
                        if (BaseViewModel::class.java.isAssignableFrom(temp)) {
                            return temp
                        }
                    } else if (temp is ParameterizedType) {
                        val rawType = temp.rawType
                        if (rawType is Class<*> && BaseViewModel::class.java.isAssignableFrom(
                                rawType
                            )
                        ) {
                            return rawType
                        }
                    }
                }
            }
        } catch (e: GenericSignatureFormatError) {
            e.printStackTrace()
        } catch (e: TypeNotPresentException) {
            e.printStackTrace()
        } catch (e: MalformedParameterizedTypeException) {
            e.printStackTrace()
        }
        return null
    }


}